using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using MishraReader.Entities;
using MishraReader.ViewModels.Base;

namespace MishraReader.ViewModels.Reader
{
    public abstract class ShareViewModelBase : DialogViewModelBase
    {
        private readonly ILightWeakEventManager _eventManager;

        private readonly List<PropertyObserver<ShareServiceViewModel>> _observers = new List<PropertyObserver<ShareServiceViewModel>>();
        private readonly IOptionsManager _optionsManager;
        private readonly ServiceType _serviceType;
        private readonly Func<IShareServicePackage, bool, ShareServiceViewModel> _shareVmFactory;


        private List<ShareServiceViewModel> _activatedServices;
        private Item _item;

        protected ShareViewModelBase(Item item, ServiceType serviceType,
                                     IOptionsManager optionsManager,
                                     ILightWeakEventManager eventManager,
                                     Func<IShareServicePackage, bool, ShareServiceViewModel> shareVmFactory)
        {
            _optionsManager = optionsManager;
            _eventManager = eventManager;
            _shareVmFactory = shareVmFactory;
            _serviceType = serviceType;
            Item = item;

            SettingsCommand = new RelayCommand(ExecuteSettingsCommand);

            _optionsManager.ActivatedServicesChanged += new EventHandler<EventArgs>(RefreshActivatedServices)
                .MakeWeak(handler => _optionsManager.ActivatedServicesChanged -= handler);

            RefreshActivatedServices(null, null);
        }

        /// <summary>
        ///   Gets the activated services.
        /// </summary>
        public List<ShareServiceViewModel> ActivatedServices
        {
            get { return _activatedServices; }
            private set
            {
                Set(ref _activatedServices, value);
            }
        }

        /// <summary>
        ///   Gets the item.
        /// </summary>
        public Item Item
        {
            get { return _item; }
            set
            {
                Set(ref _item, value);
            }
        }

        public ICommand SettingsCommand { get; private set; }

        protected virtual void OnActivatedServiceChanged()
        {
        }

        /// <summary>
        ///   Save user selection
        /// </summary>
        protected void SaveSelectedService()
        {
            foreach (var serviceViewModel in ActivatedServices)
            {
                var account = _optionsManager.ActivatedServices.FirstOrDefault(s => serviceViewModel.ServicePackage == s.ServicePackage);
                if (account != null)
                    account.IsSelected = serviceViewModel.IsActivated;
            }
        }

        private void ExecuteSettingsCommand()
        {
            ExecuteCancelCommand();

            if (_serviceType == ServiceType.Share)
                _eventManager.Send(ApplicationMessages.NavigationMessage, "Settings_SharingServices");
            else
                _eventManager.Send(ApplicationMessages.NavigationMessage, "Settings_BookmarkServices");
        }

        private void RefreshActivatedServices(object sender, EventArgs eventArgs)
        {
            _observers.ForEach(o => o.UnregisterAllHandlers());
            _observers.Clear();

            try
            {
                ActivatedServices = (from s in _optionsManager.ActivatedServices
                                     where s.ServicePackage.Service.ServiceType == _serviceType
                                     orderby s.ServicePackage.ServiceName
                                     let svm = _shareVmFactory(s.ServicePackage, s.IsSelected)
                                     select svm).ToList();


                foreach (var shareServiceViewModel in ActivatedServices)
                {
                    var obs = PropertyObserver.Create(shareServiceViewModel);
                    obs.RegisterHandler(o => o.IsActivated, _ => OnActivatedServiceChanged());

                    _observers.Add(obs);
                }
            }
            catch (Exception)
            {
                ActivatedServices = new List<ShareServiceViewModel>();
            }
           

        }
    }
}